package me.jiatao.wan.ui.login

import android.os.Bundle
import android.view.View
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.addTextChangedListener
import androidx.lifecycle.lifecycleScope
import app.rive.runtime.kotlin.RiveAnimationView
import com.google.android.material.snackbar.Snackbar
import com.hi.dhl.binding.databind
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import me.jiatao.eventbus.post.postEvent
import me.jiatao.wan.R
import me.jiatao.wan.data.UserEvent
import me.jiatao.wan.data.network.HttpConst
import me.jiatao.wan.data.network.doFailure
import me.jiatao.wan.data.network.doSuccess
import me.jiatao.wan.databinding.ActivityLoginBinding

@AndroidEntryPoint
class LoginActivity : AppCompatActivity() {

    private val mBinding by databind<ActivityLoginBinding>(R.layout.activity_login)
    private lateinit var riveAnimation: RiveAnimationView

    private val userViewModel by viewModels<UserViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        riveAnimation = mBinding.myRiveAnimation

        mBinding.userName.apply {
            onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
                teddyCheck(hasFocus)
            }

            addTextChangedListener(afterTextChanged = { text ->
                teddyLookAt(text?.length!! * 4)
            })
        }

        mBinding.userPwd.apply {
            onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
                teddyCheck(false)
                teddyHands(hasFocus)
            }
        }

        mBinding.loginButton.setOnClickListener { _ ->
            mBinding.userName.clearFocus()
            mBinding.userPwd.clearFocus()

            val name = mBinding.userName.text.toString()
            val pwd = mBinding.userPwd.text.toString()

            if (verifyUserInfo(name, pwd)) {
                lifecycleScope.launch {
                    userViewModel.userLogin(name, pwd).collectLatest { result ->
                        result.doFailure { apiEx ->
                            teddyFail()
                            val msg = apiEx.message ?: HttpConst.MSG_OPERATION_FAILURE
                            Snackbar.make(mBinding.cardView, msg, Snackbar.LENGTH_SHORT).show()
                        }
                        result.doSuccess { userLoginPojo ->
                            teddySuccess()
                            Snackbar.make(mBinding.cardView, "登录成功", Snackbar.LENGTH_SHORT).show()

                            /** 发送用户信息事件 */
                            postEvent(UserEvent(userLoginPojo.nickname))

                            delay(2000)
                            finish()
                        }
                    }
                }
            }
        }

        mBinding.loading = userViewModel.loading
        teddyIdle()
    }


    /**
     * 验证用户输入
     */
    private fun verifyUserInfo(name: String, pwd: String): Boolean = mBinding.run {
        userNameLayout.error = null
        userPwdLayout.error = null

        var result = true
        if (name.isEmpty()) {
            userNameLayout.error = "用户名不能为空"
            result = false
        } else if (name.length > 20) {
            userNameLayout.error = "用户名长度需要小于20"
            result = false
        }

        if (pwd.isEmpty()) {
            userPwdLayout.error = "密码不能为空"
            result = false
        } else if (pwd.length > 20) {
            userPwdLayout.error = "密码长度需要小于20"
            result = false
        }
        return@run result
    }

    //region 泰迪熊动画控制

    private fun teddyIdle() {
        teddyCheck(false)
        riveAnimation.play("idle")
    }

    private fun teddyCheck(isCheck: Boolean) {
        riveAnimation.setBooleanState("TeddyMachine", "Check", isCheck)
    }


    private fun teddyLookAt(value: Int) {
        riveAnimation.setNumberState("TeddyMachine", "Look", value.toFloat())
    }

    private fun teddyHands(isUp: Boolean) {
        riveAnimation.setBooleanState("TeddyMachine", "hands_up", isUp)
    }

    private fun teddySuccess() {
        riveAnimation.fireState("TeddyMachine", "success")
    }

    private fun teddyFail() {
        riveAnimation.fireState("TeddyMachine", "fail")
    }

    //endregion
}